package ghostcat.display.bitmap {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.utils.Timer;
	
	import ghostcat.display.IGBase;
	import ghostcat.events.GEvent;
	import ghostcat.events.MoveEvent;
	import ghostcat.events.ResizeEvent;
	import ghostcat.events.TickEvent;
	import ghostcat.parse.display.DrawParse;
	import ghostcat.parse.graphics.GraphicsBitmapFill;
	import ghostcat.util.Tick;
	import ghostcat.util.core.UniqueCall;

	public class GBitmap extends Bitmap implements IGBase, IBitmapDataDrawer {
		private var _enabled:Boolean = true;
		private var _bitmapData:BitmapData;
		public var bitmapMouseChecker:BitmapMouseChecker;
		protected var displayListCall:UniqueCall;
		public var enabledDelayUpdate:Boolean = true;
		private var _enableMouseEvent:Boolean = false;
		protected var positionCall:UniqueCall;
		private var _paused:Boolean = false;
		private var _height:Number;
		private var _cursor:Object;
		private var _refreshTimer:Timer;
		private var _position:Point;
		private var _data:Object;
		public var destoryWhenRemove:Boolean = false;
		public var enabledScale:Boolean = false;
		public var delayUpatePosition:Boolean = false;
		private var _toolTip:Object;
		public var priority:int = 0;
		private var _refreshInterval:int = 0;
		private var _oldPosition:Point;
		private var _toolTipObj:Object;
		public var destoryed:Boolean = false;
		private var _enabledTick:Boolean = false;
		private var _width:Number;
		protected var sizeCall:UniqueCall;

		public function GBitmap(param1 = null, param2:String = "auto", param3:Boolean = false) {
			_oldPosition = new Point();
			_position = new Point();
			positionCall = new UniqueCall(vaildPosition, true);
			sizeCall = new UniqueCall(vaildSize, true);
			displayListCall = new UniqueCall(vaildDisplayList);
			if (param1 is Bitmap) {
				param1 = (param1 as Bitmap).bitmapData;
			} else if (param1 is DisplayObject) {
				param1 = new DrawParse(param1 as DisplayObject).createBitmapData();
			}
			super(param1, param2, param3);
			if (bitmapData) {
				_width = bitmapData.width;
				_height = bitmapData.height;
			}
			addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
			addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
			return;
		} // end function

		override public function set y(param1:Number):void {
			if (y == param1) {
				return;
			}
			_oldPosition.y = super.y;
			position.y = param1;
			if (!delayUpatePosition) {
				super.y = param1;
			}
			if (enabledDelayUpdate) {
				positionCall.invalidate();
			}
			return;
		} // end function

		public function set enabledTick(param1:Boolean):void {
			if (_enabledTick == param1) {
				return;
			}
			_enabledTick = param1;
			if (!_paused && _enabledTick) {
				Tick.instance.addEventListener(TickEvent.TICK, tickHandler);
			} else {
				Tick.instance.removeEventListener(TickEvent.TICK, tickHandler);
			}
			return;
		} // end function

		protected function updateDisplayList():void {
			return;
		} // end function

		public function drawToShape(param1:Graphics, param2:Point):void {
			var _loc_3:* = new Point(x, y).add(param2);
			GraphicsBitmapFill.drawBitmpData(param1, bitmapData, _loc_3.x, _loc_3.y);
			return;
		} // end function

		public function get toolTipObj() {
			return _toolTipObj;
		} // end function

		protected function init():void {
			bitmapMouseChecker = new BitmapMouseChecker(this);
			bitmapMouseChecker.enabled = _enableMouseEvent;
			return;
		} // end function

		public function destory():void {
			if (destoryed) {
				return;
			}
			if (bitmapMouseChecker) {
				bitmapMouseChecker.destory();
			}
			if (bitmapData) {
				bitmapData.dispose();
				bitmapData = null;
			}
			removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
			removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
			if (parent) {
				parent.removeChild(this);
			}
			destoryed = true;
			return;
		} // end function

		public function get position():Point {
			return _position;
		} // end function

		public function get paused():Boolean {
			return _paused;
		} // end function

		protected function updatePosition():void {
			return;
		} // end function

		override public function get height():Number {
			return _height;
		} // end function

		public function set toolTipObj(param1):void {
			_toolTipObj = param1;
			return;
		} // end function

		public function get enabled():Boolean {
			return _enabled;
		} // end function

		public function invalidateDisplayList():void {
			displayListCall.invalidate();
			return;
		} // end function

		public function set position(param1:Point):void {
			x = param1.x;
			y = param1.y;
			return;
		} // end function

		public function vaildSize(param1:Boolean = false):void {
			var _loc_2:ResizeEvent = null;
			updateSize();
			if (!param1) {
				_loc_2 = new ResizeEvent(ResizeEvent.RESIZE);
				_loc_2.size = new Point(width, height);
				dispatchEvent(_loc_2);
				if (parent) {
					_loc_2 = new ResizeEvent(ResizeEvent.CHILD_RESIZE);
					_loc_2.size = new Point(width, height);
					_loc_2.child = this;
					parent.dispatchEvent(_loc_2);
				}
			}
			return;
		} // end function

		public function set data(param1):void {
			_data = param1;
			return;
		} // end function

		public function set paused(param1:Boolean):void {
			if (_paused == param1) {
				return;
			}
			_paused = param1;
			if (!_paused && _enabledTick) {
				Tick.instance.addEventListener(TickEvent.TICK, tickHandler, false, priority);
			} else {
				Tick.instance.removeEventListener(TickEvent.TICK, tickHandler);
			}
			return;
		} // end function

		public function get cursor() {
			return _cursor;
		} // end function

		public function vaildPosition(param1:Boolean = false):void {
			var _loc_2:MoveEvent = null;
			if (super.x != position.x) {
				super.x = position.x;
			}
			if (super.y != position.y) {
				super.y = position.y;
			}
			updatePosition();
			if (!param1) {
				_loc_2 = new MoveEvent(MoveEvent.MOVE);
				_loc_2.oldPosition = _oldPosition;
				_loc_2.newPosition = position;
				dispatchEvent(_loc_2);
			}
			_oldPosition = position.clone();
			return;
		} // end function

		protected function updateSize():void {
			var _loc_1:BitmapData = null;
			if (enabledScale) {
				super.width = width;
				super.height = height;
			} else {
				_loc_1 = new BitmapData(_width, _height, true, 0);
				if (bitmapData) {
					_loc_1.copyPixels(bitmapData, bitmapData.rect, new Point());
					bitmapData.dispose();
				}
				bitmapData = _loc_1;
			}
			return;
		} // end function

		public function get oldPosition():Point {
			return _oldPosition;
		} // end function

		override public function set height(param1:Number):void {
			if (_height == param1) {
				return;
			}
			_height = param1;
			if (enabledDelayUpdate) {
				sizeCall.invalidate();
			}
			return;
		} // end function

		override public function get x():Number {
			return position.x;
		} // end function

		override public function get y():Number {
			return position.y;
		} // end function

		public function set enabled(param1:Boolean):void {
			_enabled = param1;
			return;
		} // end function

		public function invalidatePosition():void {
			positionCall.invalidate();
			return;
		} // end function

		public function vaildDisplayList(param1:Boolean = false):void {
			if (!param1) {
				updateDisplayList();
			}
			dispatchEvent(new GEvent(GEvent.UPDATE_COMPLETE));
			return;
		} // end function

		public function set refreshInterval(param1:int):void {
			if (_refreshInterval == param1) {
				return;
			}
			_refreshInterval = param1;
			if (param1 == 0) {
				if (_refreshTimer) {
					_refreshTimer.removeEventListener(TimerEvent.TIMER, refreshHandler);
					_refreshTimer.stop();
					_refreshTimer = null;
				}
			} else if (!_refreshTimer) {
				_refreshTimer = new Timer(param1, int.MAX_VALUE);
				_refreshTimer.addEventListener(TimerEvent.TIMER, refreshHandler);
				_refreshTimer.start();
			} else {
				_refreshTimer.delay = param1;
			}
			return;
		} // end function

		public function get enabledTick():Boolean {
			return _enabledTick;
		} // end function

		override public function set width(param1:Number):void {
			if (_width == param1) {
				return;
			}
			_width = param1;
			if (enabledDelayUpdate) {
				sizeCall.invalidate();
			}
			return;
		} // end function

		private function addedToStageHandler(event:Event):void {
			removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
			init();
			return;
		} // end function

		public function set cursor(param1):void {
			_cursor = param1;
			return;
		} // end function

		public function set enableMouseEvent(param1:Boolean):void {
			_enableMouseEvent = param1;
			if (bitmapMouseChecker) {
				bitmapMouseChecker.enabled = param1;
			}
			return;
		} // end function

		private function removedFromStageHandler(event:Event):void {
			if (destoryWhenRemove) {
				destory();
			}
			return;
		} // end function

		public function drawToBitmapData(param1:BitmapData, param2:Point):void {
			if (bitmapData) {
				param1.copyPixels(bitmapData, bitmapData.rect, position.add(param2));
			}
			return;
		} // end function

		public function get data() {
			return _data;
		} // end function

		public function get refreshInterval():int {
			return _refreshInterval;
		} // end function

		public function getBitmapUnderMouse(param1:Number, param2:Number):Array {
			return uint(bitmapData.getPixel32(param1 - x, param2 - y) >> 24) > 0 ? ([this]) : (null);
		} // end function

		public function setPosition(param1:Point, param2:Boolean = false):void {
			var _loc_3:* = new Point(super.x, super.y);
			if (!_loc_3.equals(param1)) {
				_oldPosition = _loc_3;
				position = param1;
				if (!delayUpatePosition) {
					super.x = param1.x;
					super.y = param1.y;
				}
			}
			if (enabledDelayUpdate) {
				vaildPosition(param2);
			}
			return;
		} // end function

		public function set toolTip(param1):void {
			_toolTip = param1;
			return;
		} // end function

		public function invalidateSize():void {
			sizeCall.invalidate();
			return;
		} // end function

		override public function get width():Number {
			return _width;
		} // end function

		public function get toolTip() {
			return _toolTip;
		} // end function

		public function get enableMouseEvent():Boolean {
			return _enableMouseEvent;
		} // end function

		protected function tickHandler(event:TickEvent):void {
			invalidateDisplayList();
			return;
		} // end function

		private function refreshHandler(event:TimerEvent):void {
			invalidateDisplayList();
			return;
		} // end function

		override public function set bitmapData(param1:BitmapData):void {
			var _loc_2:* = param1;
			super.bitmapData = param1;
			_bitmapData = _loc_2;
			if (bitmapData) {
				_width = bitmapData.width;
				_height = bitmapData.height;
			}
			return;
		} // end function

		override public function set x(param1:Number):void {
			if (x == param1) {
				return;
			}
			_oldPosition.x = super.x;
			position.x = param1;
			if (!delayUpatePosition) {
				super.x = param1;
			}
			if (enabledDelayUpdate) {
				positionCall.invalidate();
			}
			return;
		} // end function

	}
}
